﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using System.Timers;
using System.Threading;
using System.Management;
using System.Diagnostics;
using System.Collections.ObjectModel;

namespace SeriesCommunicationDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private DispatcherTimer autoDetectionTimer = new DispatcherTimer();
        private DispatcherTimer autoSendTimer = new DispatcherTimer();
        private DispatcherTimer clockTimer = new DispatcherTimer();
        private DispatcherTimer recTimer = new DispatcherTimer();

        private DispatcherTimer cmdTimer = new DispatcherTimer();

        private SerialPort serial = new SerialPort();
        private UInt32 sendByteCount;
        private UInt32 recByteCount;
        private TimeSpan tSpace;
        private string sendData="";

        private UInt16 waterId=0;
        private uint waterAddrSW = 0;

        byte sendEndByte;

        private UInt64 newAddr=0x10203040506070; 
        private UInt64 newTime=0x20170807113045; 

        public string[] sendCmdArray;

        private struct operateConfig
        {
            public bool serialSwitch;
            public bool stopReceive;
            public bool receiveHex;
            public bool sendHex;
            public bool autoAddCheckSumToHex;
        }

        private operateConfig gOperate;
        private Queue<byte> gRecByteQueue = new Queue<byte>();

        private Object thisObject = new Object();
        ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity");
         Stopwatch sw=new Stopwatch();

        public MainWindow()
        {
            InitializeComponent();
            GetValuablePortName();

            sendCmdArray = new string[]
            {
                "None",//0;
                "WsetNo",
                "WsetTimeCalc",
                "WsetValue",
                "WgetValue",//4;

                "CsetNo",//5
                "CgetNo",
                "CsetTimeCalc",
                "CgetTimeCalc",
                "CsetPeriod",
                "CgetPeriod",
                "CgetSYNC",
                "CgetNormal",
                "CaddNo",//13
                "CdeleteNo",
                "CmodifyNo",
                "Creset",
                "Cresume",
                "CsetIPport",
                "CgetIPport",
                "CgetVersion",//19
            };
            cbCMD0.ItemsSource = sendCmdArray;
            cbCMD1.ItemsSource = sendCmdArray;
            cbCMD2.ItemsSource = sendCmdArray;
            cbCMD3.ItemsSource = sendCmdArray;

            FileInfo fi = new FileInfo(@"SeriesCommunicationDemo.exe");
            string strpath=System.Environment.CurrentDirectory;
            if(fi.Exists)
            {
                string modifyTime = fi.LastWriteTime.ToString();
                this.Title = "Compile time:"+modifyTime;
            }   
            else
            {
                this.Title = strpath;
            }

            autoDetectionTimer.Interval = new TimeSpan(0,0,0,0,500);//100ms onetims;
            autoDetectionTimer.Tick += new EventHandler(AutoDetectionTimer_Tick);

            clockTimer.Interval = new TimeSpan(0, 0, 0, 1);//1s onetims;
            clockTimer.Tick += new EventHandler(ClockTimer_Tick);

            recTimer.Interval = new TimeSpan(0,0,0,0,50);//50ms;
            recTimer.Tick += RecTimer_Tick;

            autoSendTimer.Tick += new EventHandler(AutoSendTimer_Tick);
            cmdTimer.Tick += new EventHandler(CmdSendTimer_Tick);

            autoDetectionTimer.Start();
            clockTimer.Start();

            tbStatusInfo.Text = "serial is ready!";
        }

        private void ClockTimer_Tick(object sender, EventArgs e)
        {
            string dateString = "";
            DateTime now = DateTime.Now;
            dateString = string.Format("{0}-{1}-{2} {3}:{4}:{5}",
                now.Year,
                now.Month.ToString("00"),
                now.Day.ToString("00"),
                now.Hour.ToString("00"),
                now.Minute.ToString("00"),
                now.Second.ToString("00")
                );
            tbDate.Text = dateString;
        }

        private void AutoDetectionTimer_Tick(object sender, EventArgs e)
        {
            string[] serialPortName = SerialPort.GetPortNames();
            if (gOperate.serialSwitch == true)
            {
                foreach(string portName in serialPortName)
                {
                    if (portName == serial.PortName)
                        return;
                }
                btnSwitch.IsChecked = false;

                cbPorts.Items.Remove(serial.PortName);
                cbPorts.SelectedIndex = 0;

                tbStatusInfo.Text = "serial invalid!";
            }
            else
            {
                if(cbPorts.Items.Count!=serialPortName.Length)
                {
                    cbPorts.Items.Clear();
                  //  foreach(string portName in serialPortName)
                  //  {
                        string deviceName = "";
                        ManagementObjectCollection hardInfors = mos.Get();
                        foreach(var hardInfor in hardInfors)
                        {
                            if((hardInfor.Properties["Name"].Value!=null)&&(hardInfor.Properties["Name"].Value
                                .ToString().Contains("(COM")))
                            {
                                 deviceName = hardInfor.Properties["Name"].Value.ToString();
                                 cbPorts.Items.Add(deviceName);
                            }
                        }
                  //  }

                    cbPorts.SelectedIndex = 0;

                    tbStatusInfo.Text = "serial has updated!";
                }
            }
        }

        private void GetValuablePortName()
        {
            string[] serialPortName = SerialPort.GetPortNames();
            cbPorts.Items.Clear();
           // foreach (string portName in serialPortName)
          //  {
                string deviceName = "";
                ManagementObjectCollection hardInfors = mos.Get();
                foreach (var hardInfor in hardInfors)
                {
                    if ((hardInfor.Properties["Name"].Value != null) && (hardInfor.Properties["Name"].Value
                        .ToString().Contains("(COM")))
                    {
                        deviceName = hardInfor.Properties["Name"].Value.ToString();
                        cbPorts.Items.Add(deviceName);
                    }
                }
           // }
        }

        private void btnSwitch_Checked(object sender, RoutedEventArgs e)
        {
            if (cbPorts.Text != "")
            {
                try
                {
                    int i1 = cbPorts.Text.LastIndexOf('(');
                    string pn = cbPorts.Text.Substring(i1 + 1, cbPorts.Text.Length - i1 - 2);
                    serial.PortName = pn;
                    serial.BaudRate = Convert.ToInt32(cbBradRate.Text);
                    serial.DataBits = Convert.ToInt32(cbWorldLenth.Text);
                    serial.Parity = (Parity)Enum.Parse(typeof(Parity), cbParity.Text);
                    serial.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cbStopBit.Text);
                    serial.RtsEnable = false;
                    if (cbHwFlow.Text != "None")
                    {
                        serial.RtsEnable = true;
                    }
                    serial.Encoding = Encoding.ASCII;
                    serial.DiscardNull = false;
                    serial.ReceivedBytesThreshold = 1;
                    serial.ReadTimeout = 0x7fff_ffff;
                    serial.ReadBufferSize = 0x1000;
                    serial.WriteBufferSize = 0x800;
                    serial.WriteTimeout = 0x7fff_ffff;

                    serial.DataReceived += ReceiveData;

                    serial.Open();

                    serial.DiscardInBuffer();
                    serial.DiscardOutBuffer();

                    serialSettingControlState(false);

                    btnSwitch.Content = "Close";

                    epSerialStatus.Fill = Brushes.Red;
                    btnManualSend.IsEnabled = true;
                    btnStopReceiver.IsEnabled = true;
                    cbAutoSend.IsEnabled = true;
                    gOperate.serialSwitch = true;
                    tbStatusInfo.Text = "serial is Opened!";
                }
                catch
                {
                    tbStatusInfo.Text = "serial Config erro!";
                }
            }
            else
            {
                tbStatusInfo.Text = "serial no port is selected!";
            }
            
        }

        private void serialSettingControlState(bool state)
        {
            cbPorts.IsEnabled = state;
            cbBradRate.IsEnabled = state;
            cbWorldLenth.IsEnabled = state;
            cbParity.IsEnabled = state;
            cbStopBit.IsEnabled = state;
            cbHwFlow.IsEnabled = state;
        }

       // private delegate void UpdateUiTextDeleget(byte[] text);

        private void ReceiveData(object sender, SerialDataReceivedEventArgs e)
        {
            //string readStr=serial.ReadExisting();
            int bytes = serial.BytesToRead;
            byte[] tempBuffer = new byte[bytes];

            serial.Read(tempBuffer, 0,bytes);

            //if (bFirstReceive == true)
            //{
            //    this.Dispatcher.Invoke(new Action(() =>
            //    {
            //        if (gOperate.stopReceive == false)
            //        {
            //            rtReceive.AppendText("        Time:" + DateTime.Now.ToString("yyyy-M-d HH:MM:ss") + "\n");
            //            rtReceive.AppendText("Rx:");
            //        }
            //    }));                
            //    bFirstReceive = false;
            //}

            foreach(byte bb in tempBuffer)
            {
                gRecByteQueue.Enqueue(bb);
            }            

            if (gRecByteQueue.Count>=128)
            {
                Thread recHandler = new Thread(new ThreadStart(RecDataHandler));
                recHandler.Start();
            }           
            
            recTimer.Start();            
        }

        private void RecTimer_Tick(object sender, EventArgs e)
        {
            recTimer.Stop();

            if (gRecByteQueue.Count < 128)
            {
                Thread recHandler = new Thread(new ThreadStart(RecDataHandler));
               // recHandler.IsBackground = true;
                recHandler.Start();
            }
        }

        private void RecDataHandler()
        {
            sw.Stop();
            tSpace = sw.Elapsed;
            Queue<byte> recQueue = new Queue<byte>();
            recQueue.Clear();
            lock (thisObject)
            {
                int count = gRecByteQueue.Count;
                for (int i=0;i<count;i++)
                {
                    recQueue.Enqueue(gRecByteQueue.Dequeue());
                }
            }            

            recByteCount += (UInt32)recQueue.Count;
            string recStr = "";
            if (gOperate.receiveHex == false)
            {                    
                recStr+= Encoding.ASCII.GetString(recQueue.ToArray<byte>())+" ";
            }
            else
            {
                //string tempStr;
                foreach (byte bb in recQueue)
                {
                    //tempStr = (Convert.ToString(bb, 16)).ToUpper();
                    recStr+= string.Format("{0:x2}", bb).ToUpper()+" ";
                }
            }
            recStr += "\n";


            this.Dispatcher.Invoke(new Action(()=>
            {
                if (gOperate.stopReceive == false)
                {
                    tbRxCnt.Text = recByteCount.ToString();
                    tbTimeSpace.Text =((long)tSpace.TotalMilliseconds).ToString();//Convert.ToString(tSpace.Milliseconds);
                    rtReceive.AppendText(recStr);
                    rtReceive.ScrollToEnd();
                }
            }));
        }

        private void btnSwitch_Unchecked(object sender, RoutedEventArgs e)
        {
            try
            {
                recTimer.Stop();
                autoSendTimer.Stop();
                serial.Close();

                serialSettingControlState(true);
                tbStatusInfo.Text = "serial is closed!";
                btnSwitch.Content = "Open";
                epSerialStatus.Fill = Brushes.Gray;
                btnManualSend.IsEnabled = false;
                btnStopReceiver.IsEnabled = false;
                cbAutoSend.IsEnabled = false;
                gOperate.serialSwitch = false;
            }
            catch
            {
                tbStatusInfo.Text = "serial Close erro!";
            }
        }

        private void tbtnStopReceiver_Checked(object sender, RoutedEventArgs e)
        {
            gOperate.stopReceive = true;
            btnStopReceiver.Content = "Resume Receive";
        }

        private void tbtnStopReceiver_Unchecked(object sender, RoutedEventArgs e)
        {
            gOperate.stopReceive = false;
            btnStopReceiver.Content = "Stop Receive";
        }

        private void btnManualSend_Click(object sender, RoutedEventArgs e)
        {
            sendData = tbSend.Text;
            Thread sendHandler = new Thread(new ThreadStart(SerialPortSendHandler));
            sendHandler.Start();              
        }

        private void InputStrToByteArray(string inStr,out byte[] outByte)
        {
            string tempStr = inStr.Replace("0x", "");
            inStr = tempStr.Replace("0X", "");
            tempStr = inStr.Trim();
            string infoStr = "";

            string[] sendString = tempStr.Split(
                new char[] { ',', '，', '\t', '\n', ' ', '\r', '+' });
            List<string> strList = new List<string>();
            foreach (string str in sendString)
            {
                try
                {
                    string temStr = str;
                    string numStr;
                    do
                    {
                        if (temStr.Length > 2)
                        {
                            numStr = temStr.Substring(0, 2);
                            temStr = temStr.Remove(0, 2);
                            strList.Add(numStr);
                        }
                        else
                        {
                            strList.Add(temStr);
                            break;
                        }
                    } while (true);
                }
                catch
                {

                    infoStr = "send data format erro!";
                }
            }
            outByte = new byte[strList.Count];
            uint i = 0;
            foreach (string str in strList)
            {
                int strNumber;
                try
                {
                    if(str!="")
                    {
                        strNumber = Convert.ToInt16(str, 16);
                        outByte[i] = Convert.ToByte(strNumber);
                    }
                    else
                    {
                        outByte[i] = 0;
                    }
                    //callbackStr += str + " ";
                    i++;
                }
                catch
                {
                    infoStr = "send data format erro!";
                }

            }
            this.Dispatcher.Invoke(new Action(() =>
            {
                if (infoStr != "")
                    tbStatusInfo.Text = infoStr;
            }));
        }

        private void SerialPortSendHandler()
        {
            string cntStr = "";
            string infoStr = "";
            byte[] sendByte;
            uint i = 0;
            if (!serial.IsOpen)
            {
                infoStr = "Please open serial port!";
            }
            else
            {
                string callbackStr = "";
                if (gOperate.sendHex == false)
                {
                    if(sendEndByte!=0)
                    {
                        char c = Convert.ToChar(sendEndByte);
                        sendData += c;
                    }                    
                    serial.Write(sendData);
                    sendByteCount += (UInt32)sendData.Length;
                    callbackStr = sendData;
                }
                else
                {
                    InputStrToByteArray(sendData,out sendByte);                    

                    if(gOperate.autoAddCheckSumToHex && sendByte.Length>4)
                    {
                        byte checkSum = 0;
                        for (i = 0; i < (sendByte.Length - 5) ;i++)
                        {
                            checkSum += sendByte[i+3];
                        }
                        sendByte[sendByte.Length - 2] = checkSum;
                    }
                    serial.Write(sendByte, 0, sendByte.Length);
                    sendByteCount += (UInt32)sendByte.Length;
                }
                this.Dispatcher.Invoke(new Action(() =>
                {
                    cntStr = sendByteCount.ToString();
                }));
                sw.Reset();
                sw.Start();
            }
            this.Dispatcher.Invoke(new Action(() =>
            {
                if(cntStr!="")
                    tbTxCnt.Text = cntStr;
                if (infoStr != "")
                    tbStatusInfo.Text = infoStr;
            }));
        }

        private void btnClearReceiver_Click(object sender, RoutedEventArgs e)
        {
            rtReceive.Document.Blocks.Clear();
        }

        private void btnCleanSend_Click(object sender, RoutedEventArgs e)
        {
            tbSend.Text = "";
        }

        private void cbAutoSend_Checked(object sender, RoutedEventArgs e)
        {
            UInt16 intervalTime;
            try
            {
                intervalTime = Convert.ToUInt16(tbInterval.Text);
            }
            catch
            {
                tbStatusInfo.Text = "input interval time erro!";
                return;
            }
            autoSendTimer.Interval = new TimeSpan(0, 0, 0, 0, intervalTime);
            autoSendTimer.Start();
        }

        private void AutoSendTimer_Tick(object sender, EventArgs e)
        {
            if (tbSend.Text != "")
            {
                sendData = tbSend.Text;
                Thread sendHandler = new Thread(new ThreadStart(SerialPortSendHandler));
                sendHandler.Start();
            }
            else
            {
                tbStatusInfo.Text = "Please input send data";
            }
        }

        private void cbAutoSend_Unchecked(object sender, RoutedEventArgs e)
        {
            autoSendTimer.Stop();
        }

        private void btnCleanCnt_Click(object sender, RoutedEventArgs e)
        {
            tbTxCnt.Text = "0";
            recByteCount = 0;
            tbRxCnt.Text = "0";
            sendByteCount = 0;
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            string path = @"TestHistoryData.txt";
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Title = "Please Select Save Path...";
            //sfd.FileName = string.Format("Record_{0}", DateTime.Now.ToString("yyyyMdHHMMss"));
            sfd.FileName = "";
            sfd.Filter = "Text Document|*.txt";

            if (sfd.ShowDialog() == true)
            {
                path = sfd.FileName;
                SaveData(path);
            }            
        }

        private void SaveData(string path)
        {
            try
            {
                using (StreamWriter sw=new StreamWriter(path))
                {
                    string text = (new TextRange(rtReceive.Document.ContentStart, rtReceive.Document.ContentEnd)).Text;
                    sw.Write(text);
                    tbStatusInfo.Text = "save data success!";
                }
            }
            catch
            {
                tbStatusInfo.Text = "save data erro!";
            }
        }
        
        private void cbReceiveHex_Checked(object sender, RoutedEventArgs e)
        {
            gOperate.receiveHex = true;
        }

        private void cbReceiveHex_Unchecked(object sender, RoutedEventArgs e)
        {
            gOperate.receiveHex = false;
        }

        private void cbSendHex_Checked(object sender, RoutedEventArgs e)
        {
            gOperate.sendHex = true;
        }

        private void cbSendHex_Unchecked(object sender, RoutedEventArgs e)
        {
            gOperate.sendHex = false;
        }
        /// <summary>
        /// 窗口关闭前的处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (serial.IsOpen)
            {
                recTimer.Stop();
                autoSendTimer.Stop();
                autoDetectionTimer.Stop();
                clockTimer.Stop();
                cmdTimer.Stop();

                serial.Close();
            }
        }

        private void cbAutoCheckSum_Checked(object sender, RoutedEventArgs e)
        {
            gOperate.autoAddCheckSumToHex = true;
            cbSendHex.IsChecked = true;
            gOperate.sendHex = true;
        }

        private void cbAutoCheckSum_Unchecked(object sender, RoutedEventArgs e)
        {
            gOperate.autoAddCheckSumToHex = false;
            cbSendHex.IsChecked = false;
            gOperate.sendHex = false;
        }

        UInt16[] intervalTime=new UInt16[4];
        private int cmdSendCnt;

        private void btnAuto_Click(object sender, RoutedEventArgs e)
        {
            UInt16 tempU16=0;
            string infoStr = "";
            cmdSendCnt = 0;
            try
            {
                if (tbInterval0.Text != "")
                    tempU16 = Convert.ToUInt16(tbInterval0.Text);
                else
                    tempU16 = 0;
                intervalTime[0] = tempU16;
                if (tbInterval1.Text != "")
                    tempU16 = Convert.ToUInt16(tbInterval1.Text);
                else
                    tempU16 = 0;
                intervalTime[1] = tempU16;
                if (tbInterval2.Text != "")
                    tempU16 = Convert.ToUInt16(tbInterval2.Text);
                else
                    tempU16 = 0;
                intervalTime[2] = tempU16;
                if (tbInterval3.Text != "")
                    tempU16 = Convert.ToUInt16(tbInterval3.Text);
                else
                    tempU16 = 0;
                intervalTime[3] = tempU16;
            }
            catch
            {
                infoStr = "input interval time erro!";
            }
            this.Dispatcher.Invoke(new Action(() =>
            {
                if (infoStr != "")
                    tbStatusInfo.Text = infoStr;
            }));
            cmdSendCnt = 0;
            cmdTimer.Interval = new TimeSpan(0, 0, 0, 0, intervalTime[cmdSendCnt]);
            cmdTimer.Start();
        }

        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            cmdTimer.Stop();
            cmdSendCnt = 0;
        }

        private void CmdSendTimer_Tick(object sender, EventArgs e)
        {
            cmdTimer.Stop();
            switch (cmdSendCnt)
            {
                case 0:
                    SendSingleCmd(tbAddr0, cbCMD0);
                    break;
                case 1:
                    SendSingleCmd(tbAddr1, cbCMD1);
                    break;
                case 2:
                    SendSingleCmd(tbAddr2, cbCMD2);
                    break;
                case 3:
                    SendSingleCmd(tbAddr3, cbCMD3);
                    break;
                default: break;
            }
            cmdTimer.Interval = new TimeSpan(0, 0, 0, 0, intervalTime[cmdSendCnt++]);
            if(cmdSendCnt>3)
            {
                cmdSendCnt = 0;
            }
            cmdTimer.Start();
        }

        private void btnSingle_Click(object sender, RoutedEventArgs e)
        {
            var btn = sender as Button;
            switch (btn.Name)
            {
                case "send0":
                    SendSingleCmd(tbAddr0, cbCMD0);
                    break;
                case "send1":
                    SendSingleCmd(tbAddr1, cbCMD1);
                    break;
                case "send2":
                    SendSingleCmd(tbAddr2, cbCMD2);
                    break;
                case "send3":
                    SendSingleCmd(tbAddr3, cbCMD3);
                    break;
                default: break;
            }
        }

        private void SendSingleCmd(TextBox tbAddr, ComboBox cbCMD)
        {
            /*input check*/
            byte[] newAddr = {0x11,0x22,0x33,0x44,0x55,0x66,0x77};
            string infoStr = "";
            byte[] addrByte;
            byte[] cmdByte;
            uint checkSum=0;
            try
            {
                InputStrToByteArray(tbAddr.Text, out addrByte);
                int strx = cbCMD.SelectedIndex;
                GetCmdByte(strx, out cmdByte);
                if (cmdByte.Length>0)
                {
                    int length = addrByte.Length + cmdByte.Length + 7;
                    byte[] totalByte = new byte[length];
                    addrByte.CopyTo(totalByte, 5);
                    if (strx < 5)
                    {
                        totalByte[3] = 0x68;
                        totalByte[4] = 0x10;
                    }
                    cmdByte.CopyTo(totalByte, 12);
                    totalByte[0] = 0xfe;
                    totalByte[1] = 0xfe;
                    totalByte[2] = 0xfe;
                    totalByte[length - 1] = 0x16;
                    checkSum = 0;
                    for (int i = 0; i < (length - 5); i++)
                    {
                        checkSum += totalByte[3 + i];
                    }
                    totalByte[length - 2] = (byte)checkSum;
                    serial.Write(totalByte, 0, totalByte.Length);
                }
                else if(addrByte.Length>0)
                {
                    byte[] totalByte;
                    switch (strx)
                    {
                        case 13:
                            totalByte = new byte[15];
                            totalByte[3] = 0x78;
                            totalByte[4] = 0x07;//length;
                            addrByte.CopyTo(totalByte, 5);//before 6byte;
                            totalByte[11] = (byte)waterId;//change last addr;
                            break;
                        case 14:
                            totalByte = new byte[15];
                            totalByte[3] = 0x79;
                            totalByte[4] = 0x07;//length;
                            addrByte.CopyTo(totalByte, 5);//before 6byte;
                            totalByte[11] = (byte)waterId;//change last addr;
                            break;
                        case 15:
                            totalByte = new byte[22];
                            totalByte[3] = 0x7a;
                            totalByte[4] = 0x0e;//length;
                            if (waterAddrSW>0)
                            {
                                waterAddrSW = 0;
                                newAddr.CopyTo(totalByte, 5);
                                addrByte.CopyTo(totalByte, 12);
                            }
                            else
                            {
                                waterAddrSW = 1;
                                addrByte.CopyTo(totalByte, 5);
                                newAddr.CopyTo(totalByte, 12);
                            }
                            break;
                        default:
                            totalByte = new byte[22];
                            totalByte[3] = 00;
                            totalByte[4] = 00;//length;
                            break;
                    }
                    totalByte[0] = 0xfe;
                    totalByte[1] = 0xfe;
                    totalByte[2] = 0xfe;

                    if (waterId > 254)
                        waterId = 0;
                    else
                        waterId++;
                    totalByte[totalByte.Length - 3] = (byte)waterId;//change ser;
                    totalByte[totalByte.Length - 1] = 0x16;
                    checkSum = 0;
                    for (int i = 0; i < (totalByte.Length - 5); i++)
                    {
                        checkSum += totalByte[3 + i];
                    }
                    totalByte[totalByte.Length - 2] = (byte)checkSum;
                    serial.Write(totalByte, 0, totalByte.Length);
                }
            }
            catch (Exception)
            {
                infoStr = "single input data erro!";

            }
            this.Dispatcher.Invoke(new Action(() =>
            {
                if (infoStr != "")
                    tbStatusInfo.Text = infoStr;
            }));
        }

        private void GetCmdByte(int number,out byte[] cmdByte)
        {
            UInt64 tempU64;
            UInt32 tempU32;
            switch (number)
            {
                case 1:
                    tempU64 = newAddr;
                    cmdByte = new byte[12];
                    cmdByte[0] = 0x15;
                    cmdByte[1] = 0x0a;
                    cmdByte[2] = 0xa0;
                    cmdByte[3] = 0x18;
                    cmdByte[4] = 0;
                    for (uint i =0;i<7;i++)
                    {
                        cmdByte[5 + i] =(byte)tempU64;
                        tempU64 >>= 8;
                    }
                    break;
                case 2:
                    tempU64 = newTime;
                    cmdByte = new byte[12];
                    cmdByte[0] = 0x04;
                    cmdByte[1] = 0x0A;
                    cmdByte[2] = 0xA0;
                    cmdByte[3] = 0x15;
                    cmdByte[4] = 0;
                    for (uint i = 0; i < 7; i++)
                    {
                        cmdByte[5 + i] = (byte)tempU64;
                        tempU64 >>= 8;
                    }
                    break;
                case 3:
                    cmdByte = new byte[10];
                    cmdByte[0] = 0x34;
                    cmdByte[1] = 0x08;
                    cmdByte[2] = 0xA0;
                    cmdByte[3] = 0xA8;
                    cmdByte[4] = 0;
                    cmdByte[5] = 0xD3;//MC
                    tempU32 = 0x13141516;
                    for (uint i=0;i<4;i++)
                    {
                        cmdByte[6 + i] = (byte)tempU32;
                        tempU32 >>= 8;
                    }
                    break;
                case 4:
                    cmdByte = new byte[5];
                    cmdByte[0] = 0x01;
                    cmdByte[1] = 0x03;
                    cmdByte[2] = 0x90;
                    cmdByte[3] = 0x2F;
                    cmdByte[4] = 0;
                    break;
                default:
                    cmdByte = new byte[0];
                    break;
            }
        }

        private void cbAddend_Checked(object sender, RoutedEventArgs e)
        {
            //cr:0x0d;
            //ctrl+z:0x1a;
            //esc:0x1b;
            RadioButton rbSelect = sender as RadioButton;
            switch(rbSelect.Name)
            {
                case "rbAddCR":
                    sendEndByte = 0x0D;
                    break;
                case "rbAddCtrlZ":
                    sendEndByte = 0x1A;
                    break;
                case "rbAddESC":
                    sendEndByte = 0x1B;
                    break;
                default:
                    sendEndByte = 0;
                    break;
            }
        }

        private void tbAddr0_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.Key==Key.Enter)
            {
                byte[] addrByte;
                InputStrToByteArray(tbAddr0.Text, out addrByte);
                waterId = addrByte[6];
            }
        }
    }
}
